package com.cj.media.mediacodec

import android.hardware.display.DisplayManager
import android.media.MediaCodec
import android.media.MediaCodecInfo
import android.media.MediaFormat
import android.media.projection.MediaProjection
import com.cj.media.mediacodec.utils.FileUtils

class ScreenCaptureEncoder(
    private val mediaProjection: MediaProjection,//数据源
    private val width: Int,
    private val height: Int
) : H264Encoder {

    //编码器
    private var mediaCodec:MediaCodec

    init {
        mediaCodec = MediaCodec.createEncoderByType("video/avc")
        //编码
        val format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC,width, height)
        //1s 20帧数据
        format.setInteger(MediaFormat.KEY_FRAME_RATE,20)
        //30帧一个I帧
        format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,30)
        //码率 ，1s编码出来的字节码数
        format.setInteger(MediaFormat.KEY_BIT_RATE,width * height)
        //数据来源，数据来自surface
        format.setInteger(MediaFormat.KEY_COLOR_FORMAT,MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface)
        //编码标志位
        mediaCodec.configure(format,null,null, MediaCodec.CONFIGURE_FLAG_ENCODE)//CONFIGURE_FLAG_ENCODE表示编码
        //场地，虚拟的
        val surface = mediaCodec.createInputSurface()
        //绑定Surface，录屏的数据可以直接显示到Surface，也可以不同显示
        mediaProjection.createVirtualDisplay("cj_screen_capture",width,height,2,
            DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC,surface,null,null)
    }

    override fun encode() {
        mediaCodec.start()
        val info = MediaCodec.BufferInfo()
        while (true){
            //直接拿到输出，不用管输入，输入已经被实现了
            val outIndex = mediaCodec.dequeueOutputBuffer(info,10000)
            if(outIndex >= 0){
                //编码的数据
                val byteBuffer = mediaCodec.getOutputBuffer(outIndex)?:continue
                val bytes = ByteArray(byteBuffer.remaining())
                //将容器的byteBuffer  内部的数据 转移到 byte[]中
                byteBuffer.get(bytes)
                FileUtils.writeBytes(bytes,null)
                FileUtils.writeContent(bytes,null)
                mediaCodec.releaseOutputBuffer(outIndex,false)
            }
        }
    }
}